﻿import { Component, ViewChild, ElementRef, Input, OnInit, Output, EventEmitter } from '@angular/core';
import { FileUploader, FileItem, ParsedResponseHeaders, FileLikeObject, FileUploaderOptions } from 'ng2-file-upload';
import { AppEnvironment } from '../../../environments/AppEnvironment';
import { AppNotification } from '../../service/Notification';
import { Loading } from '../../service/Loading';

@Component({
    selector: 'app-file-upload',
    templateUrl: './app-file-upload.html',
    styleUrls: ['./app-file-upload.scss']
})

export class AppFileUpload implements OnInit {

    /**
     * 文件上传组件
     *
     * @type {FileUploader}
     * @memberof AppFileUpload
     */
    public uploader: FileUploader;

    /**
     * 已上传文件
     *
     * @type {any[]}
     * @memberof AppFileUpload
     */
    public files: any[] = [];

    /**
     * 上传或下载的地址
     *
     * @type {string}
     * @memberof AppFileUpload
     */
    public url: string = '';

    /**
     * 限制文件上传个数
     *
     * @type {number}
     * @memberof AppFileUpload
     */
    public fileCount: number;

    /**
     * 限制文件上传大小
     *
     * @private
     * @type {number}
     * @memberof AppFileUpload
     */
    private fileSize: number;

    /**
     * 是否启用
     *
     * @type {boolean}
     * @memberof IBizDateTime
     */
    @Input()
    disabled: boolean = false;

    /**
     * 是否为单文件上传
     *
     * @type {boolean}
     * @memberof AppFileUpload
     */
    @Input()
    multiple: boolean = false;

    /**
     * 标签文本值
     *
     * @type {string}
     * @memberof AppFileUpload
     */
    @Input()
    labelText: string;

    /**
     * 是否必填
     *
     * @type {boolean}
     * @memberof IBizTextarea
     */
    @Input()
    allowEmpty: boolean;

    /**
     * 编辑器参数
     *
     * @memberof AppFileUpload
     */
    @Input()
    set params(val: any) {
        if (val) {
            const { filecount, filesize } = val;
            if (filecount) {
                this.fileCount = filecount;
            }
            if (filesize) {
                this.fileSize = filesize;
            }
        }
    }

    /**
     * 
     *
     * @type {ElementRef}
     * @memberof AppFileUpload
     */
    @ViewChild('fileUpload')
    fileUpload: ElementRef;
    /**
     * 值
     *
     * @memberof AppFileUpload
     */
    @Input()
    set value(value: any) {
        if (value) {
            this.files = [];
            let val;
            if (typeof (value) === 'string') {
                try {
                    val = JSON.parse(value);
                } catch (error) {
                    console.log(error);
                }
            } else {
                val = value;
            }
            if (val instanceof Array) {
                this.files = [...val];
            }
        }else{
            this.files = [];
        }
    }
    /**
     * 
     *
     * @type {EventEmitter<any>}
     * @memberof AppFileUpload
     */
    @Output()
    valueChange: EventEmitter<any> = new EventEmitter();

    /**
     * 
     * @param {notification} Notification
     * @param {IBizLoading} loading
     * @memberof AppFileUpload
     */
    constructor(
        public notification: AppNotification,
        public loading: Loading) {
        this.uploader = new FileUploader({ url: AppEnvironment.BaseUrl + AppEnvironment.UploadFile, autoUpload: true });
        this.uploader.onSuccessItem = this.successItem.bind(this);
        this.uploader.onErrorItem = this.errorItem.bind(this);
        this.uploader.onBeforeUploadItem = this.beforeUploadItem.bind(this);
        this.uploader._fileSizeFilter = this.fileSizeFilter.bind(this);

        // 拼接上传或下载的url
        this.url = AppEnvironment.BaseUrl + AppEnvironment.ExportFile + '/';
    }

    public ngOnInit() {
        this.uploader.setOptions({
            maxFileSize: this.fileSize
        });
    }

    /**
     * 验证文件大小
     *
     * @param {FileLikeObject} [item]
     * @param {FileUploaderOptions} [options]
     * @returns {boolean}
     * @memberof AppFileUpload
     */
    public fileSizeFilter(item?: FileLikeObject): boolean {
        if (item && this.fileSize && ((item.size / 1000) >= this.fileSize)) {
            this.notification.warning(`文件大小不可超过${this.fileSize}kb`);
            return false;
        }
        return true;
    }

    /**
     * 文件选择
     *
     * @returns {*}
     * @memberof AppFileUpload
     */
    public fileSelect(): any {
        this.fileUpload.nativeElement.click();
    }

    /**
     * 删除文件
     *
     * @param {string} id
     * @param {number} index
     * @memberof AppFileUpload
     */
    public async deleteFile(id: string, index: number) {
        const res = await this.notification.confirm('确认删除', '确认删除文件吗?');
        if (res) {
            if (this.files[index] && Object.is(this.files[index].id, id)) {
                this.files.splice(index, 1);
                this.valueChange.emit(JSON.stringify(this.files));
            }
        }
    }

    /**
    * 打开新窗口进行文件下载
    * 
    * @param {any} file 
    * @memberof FileUploadPickerComponent
    */
    public async downloadFile(file) {
        const res = await this.notification.confirm('下载', '确认下载文件吗?');
        if (res) {
            window.open(AppEnvironment.BaseUrl + AppEnvironment.ExportFile + `?fileid=${file.id}`, '_blank');
        }
    }

    /**
     * 
     *
     * @param {FileItem} item
     * @param {string} response
     * @param {number} status
     * @param {ParsedResponseHeaders} headers
     * @memberof AppFileUpload
     */
    public async errorItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): Promise<any> {
        await this.loading.unmask();
        this.notification.error(`文件：${item.file.name}，上传失败`);
    }

    /**
     *
     *
     * @param {FileItem} fileItem
     * @memberof AppFileUpload
     */
    public async beforeUploadItem(fileItem: FileItem): Promise<any> {
        await this.loading.mask('文件上传中...');
    }

    /**
     * 上传成功
     *
     * @param {FileItem} item
     * @param {string} response
     * @param {number} status
     * @param {ParsedResponseHeaders} headers
     * @returns {*}
     * @memberof AppFileUpload
     */
    public async successItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): Promise<any> {
        await this.loading.unmask();
        if (this.fileCount && this.fileCount <= this.files.length) {
            return;
        }
        const res: any = JSON.parse(response);
        if (res && res.id) {
            this.files.push(res);
        }
        this.valueChange.emit(JSON.stringify(this.files));
    }

}
